/**
 * 
 */
package com.googlecode.agiletools.common.lang.time;

import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.apache.commons.lang.time.DateUtils;

/**
 * @author Administrator
 * 
 */
public class DateIterator implements Iterator<Date> {

    public static void main(String[] arg) {
	Date d = Calendar.getInstance().getTime();
	d.setDate(21);
	for (int i = 0; i < 7; i++) {

	    System.out.println("Start from " + d);
	    DateIterator di = new DateIterator(d, 15, true);
	    while (di.hasNext()) {
		Date date = di.next();
		System.out.println(date);
	    }
	    d = DateUtils.addDays(d, 1);
	}
    }

    private Date start;

    private final Date end;

    private final boolean ignoreWeekend;

    /**
     * @param start
     * @param end
     */
    public DateIterator(Date start, Date end, boolean ignoreWeekend) {
	super();
	this.start = DateUtils.addDays(start, -1);
	this.end = end;
	this.ignoreWeekend = ignoreWeekend;
    }

    public DateIterator(Date start, int days, boolean ignoreWeekend) {
	super();
	this.start = DateUtils.addDays(start, -1);

	if (ignoreWeekend) {
	    days += Math.ceil(days / 7d) * 2;
	}
	this.end = DateUtils.addDays(this.start, days);

	this.ignoreWeekend = ignoreWeekend;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.util.Iterator#hasNext()
     */
    @Override
    public boolean hasNext() {
	// nextDay
	if (ignoreWeekend) {
	    skipWeekend();
	}
	return start.before(end);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.util.Iterator#next()
     */
    @Override
    public Date next() {
	if (!hasNext()) {
	    throw new NoSuchElementException();
	}

	if (ignoreWeekend) {
	    skipWeekend();
	}
	start = DateUtils.addDays(start, 1);
	return (Date) start.clone();
    }

    @Override
    public void remove() {
	throw new UnsupportedOperationException();
    }

    /**
     * @param calendar
     */
    private void skipWeekend() {
	Calendar calendar = Calendar.getInstance();
	calendar.setTime(start);
	int dow = calendar.get(Calendar.DAY_OF_WEEK);

	switch (dow) {
	case Calendar.FRIDAY:
	    start = DateUtils.addDays(start, 2);
	    break;
	case Calendar.SATURDAY:
	    start = DateUtils.addDays(start, 1);
	    break;
	}
    }

}
